package com.levy.utils.redis;

import com.levy.model.User;
import com.levy.utils.PropertiesUtil;
import com.levy.utils.SerializationUtil;
import org.apache.commons.codec.language.Soundex;
import org.apache.log4j.Logger;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by levy on 2017/11/27.
 */
public final class RedisUtil {
    private static Logger logger = Logger.getLogger(RedisUtil.class);

    private static String ADDR = "";

    private static int PORT = 6379;

    private static String AUTH = null;

    private static int MAX_ACTIVE = 300;

    private static int MAX_IDLE = 200;

    private static int MAX_WAIT = 10000;

    private static int TIMEOUT = 10000;

    private static boolean TEST_ON_BORROW = true;

    private static JedisPool jedisPool = null;

    private static Jedis jedis = null;

    /**
     * 初始化Redis连接池
     */
    static {
        try {
            init();
            logger.info("-----RedisUtil[init]------初始化Redis操作完成！" );
        } catch (Exception e) {
            logger.error("-----RedisUtil[init]------初始化Redis操作异常，" + e.getMessage());
        }
    }

    /**
     * 初始化连接池
     *
     * @see [类、类#方法、类#成员]
     */
    private synchronized static void init() {

        ADDR = PropertiesUtil.getStringValue("redis_ip");
        PORT = PropertiesUtil.getIntValue("redis_port");
        AUTH = PropertiesUtil.getStringValue("redis_pwd");
        MAX_ACTIVE = 500;
        MAX_IDLE = 5;
        MAX_WAIT = 1000;
        TIMEOUT = 1000;

        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxIdle(MAX_IDLE);
        config.setMaxWaitMillis(MAX_WAIT);
        config.setTestOnBorrow(TEST_ON_BORROW);
        config.setMaxTotal(MAX_ACTIVE);
        jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT, AUTH);
    }

    /**
     * 获取Jedis实例
     *
     * @return
     */
    private static Jedis getJedis() {
        try {
            if (jedisPool != null) {
                jedis = jedisPool.getResource();
            } else {
                init();
                jedis = jedisPool.getResource();
            }
            logger.info("-----RedisUtil[getJedis]------获取redis实例操作成功！");
        } catch (Exception e) {
            logger.error("-----RedisUtil[getJedis]------获取redis实例操作异常！" + e.getMessage());
        }
        return jedis;
    }

    /**
     * 设置单个值
     *
     * @param key
     * @param value
     * @return
     */
    public static String set(String key, String value) {
        return set(key, value, null);
    }

    /**
     * 设置单个值，并设置超时时间
     *
     * @param key
     *            键
     * @param value
     *            值
     * @param timeout
     *            超时时间（秒）
     * @return
     * @see [类、类#方法、类#成员]
     */
    public static String set(String key, String value, Integer timeout) {
        String result = null;

        Jedis jedis = RedisUtil.getJedis();
        if (jedis == null) {
            logger.error("-----RedisUtil[set]-----redis实例为空！" );
            return result;
        }
        try {
            result = jedis.set(key, value);
            if (null != timeout) {
                jedis.expire(key, timeout);
            }
            logger.info("-----RedisUtil[set]------设置redis键值对操作完成！键=" +key+"，值="+value+",有效时间="+timeout);
        } catch (Exception e) {
            logger.error("-----RedisUtil[set]------设置redis键值对操作异常！" + e.getMessage());
        } finally {
            if (null != jedis) {
//	                jedis.close();
                jedisPool.returnResource(jedis);
            }
        }
        return result;
    }

    public static String hmSet(String key, Map<String, String> map,Integer timeout) {
        String result = null;

        Jedis jedis = RedisUtil.getJedis();
        if (jedis == null) {
            logger.error("-----RedisUtil[hmSet]-----redis实例为空！" );
            return result;
        }
        try {
            result = jedis.hmset(key, map);
            if (null != timeout) {
                jedis.expire(key, timeout);
            }
            logger.info("-----RedisUtil[hmSet]------设置redis hashMap操作完成！键=" +key+"，值="+map.toString()+",有效时间="+timeout);
        } catch (Exception e) {
            logger.error("-----RedisUtil[hmSet]------设置redis hashMap操作异常！" + e.getMessage());
        } finally {
            if (null != jedis) {
//	                jedis.close();
                jedisPool.returnResource(jedis);
            }
        }
        return result;
    }


    public static List<String> hmGet(String key, String fields) {
        List<String> result = null;

        Jedis jedis = RedisUtil.getJedis();
        if (jedis == null) {
            logger.error("-----RedisUtil[hmGet]-----redis实例为空！" );
            return result;
        }
        try {
            result = jedis.hmget(key, fields);
            logger.info("-----RedisUtil[hmGet]------获取redis 单个hashMap操作完成！键=" +key+"，值="+result.toString());
        } catch (Exception e) {
            logger.error("-----RedisUtil[hmGet]------获取redis 单个hashMap操作异常！" + e.getMessage());
        } finally {
            if (null != jedis) {
//	                jedis.close();
                jedisPool.returnResource(jedis);
            }
        }
        return result;
    }

    public static Map<String, String> hmGetAll(String key) {
        Map<String, String> result = null;

        Jedis jedis = RedisUtil.getJedis();
        if (jedis == null) {
            logger.error("-----RedisUtil[hmGetAll]-----redis实例为空！" );
            return result;
        }
        try {
            result = jedis.hgetAll(key);
            logger.info("-----RedisUtil[hmGetAll]------获取redis 全部hashMap操作完成！键=" +key+"，值="+result.toString());
        } catch (Exception e) {
            logger.error("-----RedisUtil[hmGetAll]------获取redis 单个hashMap操作异常！" + e.getMessage());
        } finally {
            if (null != jedis) {
//	                jedis.close();
                jedisPool.returnResource(jedis);
            }
        }
        return result;
    }

    /**
     * 获取单个值
     *
     * @param key
     * @return
     */
    public static String get(String key) {
        String result = null;
        Jedis jedis = RedisUtil.getJedis();
        if (jedis == null) {
            logger.error("-----RedisUtil[get]-----redis实例为空！" );
            return result;
        }
        try {
            result = jedis.get(key);
            logger.info("-----RedisUtil[get]------获取redis 单个键值对操作完成！键=" +key+"，值="+result);
        } catch (Exception e) {
            logger.error("-----RedisUtil[get]------获取redis 单个键值对操作异常！" + e.getMessage());
        } finally {
            if (null != jedis) {
//	                jedis.close();
                jedisPool.returnResource(jedis);
            }
        }
        return result;
    }

    /**
     * 删除redis中数据
     *
     * @param key
     * @return
     * @see [类、类#方法、类#成员]
     */
    public static boolean del(String key) {
        Boolean result = Boolean.FALSE;
        Jedis jedis = RedisUtil.getJedis();
        if (null == jedis) {
            logger.error("-----RedisUtil[del]-----redis实例为空！" );
            return Boolean.FALSE;
        }
        try {
            jedis.del(key);
            logger.info("-----RedisUtil[del]------删除redis 单个键操作完成！键=" +key);
        } catch (Exception e) {
            logger.error("-----RedisUtil[del]------删除redis 单个键操作异常！" + e.getMessage());
        } finally {
            if (null != jedis) {
//	                jedis.close();
                jedisPool.returnResource(jedis);
            }
        }
        return result;
    }

    /**
     * 追加
     *
     * @param key
     * @param value
     * @return
     * @see [类、类#方法、类#成员]
     */
    public static Long append(String key, String value) {
        Long result = Long.valueOf(0);
        Jedis jedis = RedisUtil.getJedis();
        if (null == jedis) {
            logger.error("-----RedisUtil[append]-----redis实例为空！" );
            return result;
        }
        try {
            result = jedis.append(key, value);
            logger.info("-----RedisUtil[append]------追加redis 键值对操作完成！键=" +key+"，值="+value);
        } catch (Exception e) {
            logger.error("-----RedisUtil[append]------追加redis 键值对操作异常！" + e.getMessage());
        } finally {
            if (null != jedis) {
//	                jedis.close();
                jedisPool.returnResource(jedis);
            }
        }
        return result;
    }

    /**
     * 检测是否存在
     *
     * @param key
     * @return
     * @see [类、类#方法、类#成员]
     */
    public static Boolean exists(String key) {
        Boolean result = Boolean.FALSE;
        Jedis jedis = RedisUtil.getJedis();
        if (null == jedis) {
            logger.error("-----RedisUtil[exists]-----redis实例为空！" );
            return result;
        }
        try {
            result = jedis.exists(key);
            logger.info("-----RedisUtil[exists]------检查redis 是否存在键操作完成！键=" +key);
        } catch (Exception e) {
            logger.error("-----RedisUtil[exists]------检查redis 是否存在键操作异常！" + e.getMessage());
        } finally {
            if (null != jedis) {
//	                jedis.close();
                jedisPool.returnResource(jedis);
            }
        }
        return result;
    }

    /**
     * 获取对象   操作需要序列化工具
     * @param key
     * @return
     */
    public static Object getObjFromRedis(String key){
        byte[] result = null;
        Jedis jedis = RedisUtil.getJedis();
        if (jedis == null) {
            logger.error("-----RedisUtil[getObjFromRedis]-----redis实例为空！" );
            return result;
        }
        try {
            result = jedis.get(key.getBytes());
            logger.info("-----RedisUtil[getObjFromRedis]------从redis获取obj操作完成！键=" +key+"，值="+result);
        } catch (Exception e) {
            logger.error("-----RedisUtil[getObjFromRedis]------从redis获取obj操作异常！" + e.getMessage());
        } finally {
            if (null != jedis) {
//	                jedis.close();
                jedisPool.returnResource(jedis);
            }
        }
        return SerializationUtil.deserialize(result);
    }


    /**
     * 设置对象进redis  需要序列化工具
     * @param key
     * @param obj
     * @return
     */
    public static String  setObjToRedis(String key,Object obj){
        String result = "";
        byte[] bytes = SerializationUtil.serialize(obj);
        Jedis jedis = RedisUtil.getJedis();
        if (jedis == null) {
            logger.error("-----RedisUtil[setObjToRedis]-----redis实例为空！" );
            return result;
        }
        try {
            result = jedis.set(key.getBytes(), bytes);
            logger.info("-----RedisUtil[setObjToRedis]------redis存入obj操作完成！键=" +key+"，缓存结果="+result);
        } catch (Exception e) {
            logger.error("-----RedisUtil[setObjToRedis]------redis存入obj操作异常！" + e.getMessage());
        } finally {
            if (null != jedis) {
//	                jedis.close();
                jedisPool.returnResource(jedis);
            }
        }
        return result;

    }




    public static void main(String[] args) {
//
//        Map<String, String> m = new HashMap<String, String>();
//        m.put("a1", "123213");
//        m.put("a2", "dfsdfsdf");
//        String dddString = RedisUtil.hmSet("m2", m, 10);
//        System.out.println(dddString);

//	    	List<String>  hh = RedisUtil.hmGet("m1", "a1");
//	    	System.out.println(hh.toString());
//
//        Map<String, String> hmGetAll = RedisUtil.hmGetAll("m2");
//        System.out.println(hmGetAll.toString());

//        User u = new User();
//        u.setName("幅度萨芬");
//        u.setSex("dsfadf");
//        u.setUserId(123231);
//        RedisUtil.setObjToRedis("dfdf",u);
        User  uu = (User) RedisUtil.getObjFromRedis("dfdf");
        System.out.println(uu.toString());



    }
}
